package org.yinxianren.java.test.thread2;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Java并发API提供这样的类，它允许1个或者多个线程一直等待，直到一组操作执行完成。 这个类就是CountDownLatch类。
 * 它初始一个整数值，此值是线程将要等待的操作数。当某个线程为了想要执行这些操作而等待时， 它要使用 await()方法。
 * 此方法让线程进入休眠直到操作完成。 当某个操作结束，它使用countDown() 方法来减少CountDownLatch类的内部计数器。
 * 当计数器到达0时，这个类会唤醒全部使用await() 方法休眠的线程们。
 */
public class DemoCountDownLatch {
    public static void main(String[] args) {
        Videoconference conference=new Videoconference(10);
        Thread threadConference=new Thread(conference);
        threadConference.start();

        for(int i=0;i<10;i++){
            Participant p=new Participant(conference,"Participant"+i);
            Thread t=new Thread(p);
            t.start();
        }
    }
}
class Videoconference implements Runnable{

    private final CountDownLatch controller;

    public Videoconference(int number) {
        controller=new CountDownLatch(number);
    }

    public void arrive(String name) {
        System.out.printf(" %s has arrived",name);
        controller.countDown();
        System.out.printf("VideoConference: Waiting for %d participants.\n",controller.getCount());
    }

    @Override
    public void run() {
        System.out.printf("VideoConference: Initialization: %d participants.\n",controller.getCount());
        try {
            controller.await();
            System.out.printf("VideoConference: All the participants have come\n");
            System.out.printf("VideoConference: Let's start...\n");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

class Participant implements Runnable {

    private Videoconference conference;
    private String name;

    public Participant(Videoconference conference, String name) {
        this.conference=conference;
        this.name=name;
    }



    @Override
    public void run() {
        long duration=(long)(Math.random()*10);
        try {
            TimeUnit.SECONDS.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        conference.arrive(name);
    }
}